﻿@using Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage;
@using Microsoft.Extensions.Options;
@using SimpleIdServer.IdServer.Helpers
@using SimpleIdServer.IdServer.Website.Infrastructures
@using SimpleIdServer.IdServer.Website.Resources;
@using SimpleIdServer.IdServer.Website.Shared.Dialogs
@using SimpleIdServer.IdServer.Website.Stores.RealmStore;
@using SimpleIdServer.IdServer.Website.Stores.RegistrationWorkflowStore;
@using System.Security.Claims
@inherits Fluxor.Blazor.Web.Components.FluxorComponent
@inject NavigationManager navigationManager
@inject NotificationService notificationService
@inject DialogService dialogService
@inject ContextMenuService contextMenuService
@inject IUrlHelper urlHelper
@inject IOptions<IdServerWebsiteOptions> Options;
@inject IState<RegistrationWorkflowsState> registrationWorkflowsState
@inject IState<RealmsState> realmsState
@inject IDispatcher dispatcher

<div>
    <div class="row">
        <div class="col">
            <RadzenText class="no-margin" Text="@Global.RegistrationWorkflows" TextStyle="TextStyle.DisplayH3" />
        </div>
        <div class="col-md-3">
            <SidAuthorizeView Roles=@($"/manualidprovisioning/manage")>
                <Authorized>
                    <RadzenButton class="mb-1" Click="@(args => AddRegistrationWorkflow())" Icon="add" Text="@Global.AddRegistrationWorkflow" ButtonStyle="ButtonStyle.Primary" Size="ButtonSize.Medium"></RadzenButton>
                </Authorized>
            </SidAuthorizeView>
        </div>
    </div>

    <RadzenDataGrid @ref="registrationWorkflowsGrid"
    AllowFiltering="false"
    AllowColumnResize="true"
    AllowAlternatingRows="false"
    AllowSorting="false"
    PageSize="30"
    AllowPaging="false"
    PagerHorizontalAlign="HorizontalAlign.Left"
    ShowPagingSummary="false"
    IsLoading="@registrationWorkflowsState.Value.IsLoading"
    Count="@registrationWorkflowsState.Value.Count"
    Data="@registrationWorkflowsState.Value.RegistrationWorkflows"
    LoadData="@LoadData"
    RowRender="@RowRender"
    TItem="SelectableRegistrationWorkflow"
    ColumnWidth="300px">
        <Columns>
            <RadzenDataGridColumn TItem="SelectableRegistrationWorkflow" Filterable="false" Sortable="false" Width="80px" TextAlign="TextAlign.Center">
                <HeaderTemplate>
                    <RadzenCheckBox @bind-Value=@selectAll Change="@(args => ToggleAll(args))" TValue="bool" />
                </HeaderTemplate>
                <Template Context="data">
                    <RadzenCheckBox @bind-Value=@data.IsSelected Change="@(args => ToggleChanged(args, data))" TValue="bool" />
                </Template>
            </RadzenDataGridColumn>
            <RadzenDataGridColumn TItem="SelectableRegistrationWorkflow" Filterable="false" Sortable="false" Title="@Global.Name">
                <Template Context="data">
                    @if(string.IsNullOrWhiteSpace(data.RegistrationWorkflow.WorkflowId))
                    {
                        @data.RegistrationWorkflow.Name
                    }
                    else
                    {
                        <RadzenLink Path="@urlHelper.GetUrl($"/registrations/workflows/{data.RegistrationWorkflow.Id}")">@data.RegistrationWorkflow.Name</RadzenLink>
                    }
                </Template>
            </RadzenDataGridColumn>
            <RadzenDataGridColumn TItem="SelectableRegistrationWorkflow" Filterable="false" Sortable="false" Title="@Global.IsDefault">
                <Template Context="data">
                    <SidAuthorizeView Roles=@($"/manualidprovisioning/manage")>
                        <Authorized>
                            <RadzenCheckBox @bind-Value="@data.RegistrationWorkflow.IsDefault" Change="@(args => ToggleIsDefault(args, data))" TValue="bool"></RadzenCheckBox>
                        </Authorized>
                        <NotAuthorized>
                            <RadzenCheckBox Value="@data.RegistrationWorkflow.IsDefault" Disabled=true TValue="bool"></RadzenCheckBox>
                        </NotAuthorized>
                    </SidAuthorizeView>
                </Template>
            </RadzenDataGridColumn>
            <RadzenDataGridColumn TItem="SelectableRegistrationWorkflow" Property="RegistrationWorkflow.UpdateDateTime" Filterable="false" Sortable="false" FormatString="{0:dd/M/yyyy HH:mm:ss}" Title="@Global.UpdateDateTime" Width="80px" />
            <RadzenDataGridColumn TItem="SelectableRegistrationWorkflow" Filterable="false" Sortable="false" Width="80px" TextAlign="TextAlign.Center">
                <Template Context="data">
                    <RadzenButton Icon="more_vert" Click="@(args => ShowMoreContextMenu(data, args))" />
                </Template>
            </RadzenDataGridColumn>
        </Columns>
    </RadzenDataGrid>
</div>

@code {
    bool selectAll = false;
    string activeRealm;
    RadzenDataGrid<SelectableRegistrationWorkflow> registrationWorkflowsGrid;
    [CascadingParameter] private Task<AuthenticationState> authenticationStateTask { get; set; }
    [Inject] private IOptions<IdServerWebsiteOptions> options { get; set; }
    [Inject] private IRealmStore realmStore { get; set; }

    protected override void OnAfterRender(bool firstRender)
    {
        base.OnAfterRender(firstRender);
        if(firstRender)
        {
            SubscribeToAction<RemoveSelectedRegistrationWorkflowsSuccessAction>((act) =>
            {
                notificationService.Notify(new NotificationMessage { Severity = NotificationSeverity.Success, Summary = Global.SelectedRegistrationWorkflowRemoved });
                StateHasChanged();
            });
            SubscribeToAction<UpdateRegistrationWorkflowFailureAction>((act) =>
            {
                notificationService.Notify(new NotificationMessage { Severity = NotificationSeverity.Error, Summary = act.ErrorMessage });
                StateHasChanged();
            });
            SubscribeToAction<CreateRegistrationWorkflowSuccessAction>((act) =>
            {
                notificationService.Notify(new NotificationMessage { Severity = NotificationSeverity.Success, Summary = Global.WorkflowIsCreated });
                StateHasChanged();
            });
            if (!registrationWorkflowsState.Value.IsLoading && registrationWorkflowsGrid != null)
                registrationWorkflowsGrid?.Reload();
        }
    }

    protected override async Task OnInitializedAsync()
    {
        base.OnInitializedAsync();
        activeRealm = await GetRealm();
    }

    void LoadData(LoadDataArgs args)
    {
        var act = new GetAllRegistrationWorkflowsAction();
        dispatcher.Dispatch(act);
    }

    void ToggleAll(bool isSelected)
    {
        var act = new ToggleAllRegistrationWorkflowAction { IsSelected = isSelected };
        dispatcher.Dispatch(act);
    }

    void ToggleChanged(bool isSelected, SelectableRegistrationWorkflow registrationWorkflow)
    {
        var act = new ToggleRegistrationWorkflowAction { IsSelected = isSelected, Id = registrationWorkflow.RegistrationWorkflow.Id };
        dispatcher.Dispatch(act);
    }

    void RowRender(RowRenderEventArgs<SelectableRegistrationWorkflow> row)
    {
        const string className = "class";
        if (row.Data.IsNew)
            row.Attributes.Add(className, "new");
        else if (row.Data.IsSelected)
            row.Attributes.Add(className, "active");
        else if (row.Attributes.ContainsKey(className))
            row.Attributes.Remove(className);
    }

    void ShowMoreContextMenu(SelectableRegistrationWorkflow registrationWorkflow, MouseEventArgs args)
    {
        var authState = authenticationStateTask.Result;
        var user = authState.User;
        var realm = !options.Value.IsReamEnabled ? SimpleIdServer.IdServer.Constants.DefaultRealm : realmStore.Realm;
        var canManage = user.Claims.Any(c => c.Type == ClaimTypes.Role && c.Value.Contains($"{realm}/manualidprovisioning/manage"));
        var menuItems = new List<ContextMenuItem>();
        var ids = registrationWorkflowsState.Value.RegistrationWorkflows?.Where(c => c.IsSelected).Select(c => c.RegistrationWorkflow.Id)?.ToList() ?? new List<string>();
        if (!ids.Contains(registrationWorkflow.RegistrationWorkflow.Id))
        {
            ids.Add(registrationWorkflow.RegistrationWorkflow.Id);
        }

        if (canManage)
        {
            menuItems.Add(new ContextMenuItem { Text = Global.Delete, Value = 1 });
            if (ids.Count() == 1)
            {
                var selectedRegistrationWorkflow = registrationWorkflowsState.Value.RegistrationWorkflows.Single(r => r.RegistrationWorkflow.Id == ids.First());
                if (string.IsNullOrWhiteSpace(selectedRegistrationWorkflow.RegistrationWorkflow.WorkflowId))
                {
                    menuItems.Add(new ContextMenuItem { Text = Global.CreateWorkflow, Value = 2 });
                }
            }
        }

        menuItems.Add(new ContextMenuItem { Text = Global.Demo, Value = 3 });
        contextMenuService.Open(args, menuItems, (a) =>
        {
            if (a.Value.Equals(1))
            {
                var act = new RemoveSelectedRegistrationWorkflowsAction { Ids = ids };
                dispatcher.Dispatch(act);
                contextMenuService.Close();
                return;
            }

            if (a.Value.Equals(2))
            {
                var act = new CreateRegistrationWorkflowAction { Id = ids.First() };
                dispatcher.Dispatch(act);
                contextMenuService.Close();
                return;
            }

            if(a.Value.Equals(3))
            {
                var url = GetDemoUrl(registrationWorkflow);
                navigationManager.NavigateTo(url, true);
                contextMenuService.Close();
            }
        });
    }

    async void AddRegistrationWorkflow()
    {
        await dialogService.OpenAsync<AddRegistrationWorkflowDialog>(Global.AddRegistrationWorkflow, new Dictionary<string, object>(), new DialogOptions
        {
            Width = "700px",
            Height = "512px",
            Resizable = true,
            Draggable = true
        });
    }

    void ToggleIsDefault(bool isSelected, SelectableRegistrationWorkflow workflow)
    {
        var updateRegistrationWorkflow = new UpdateRegistrationWorkflowAction { Id = workflow.RegistrationWorkflow.Id, IsDefault = isSelected, Name = workflow.RegistrationWorkflow.Name };
        dispatcher.Dispatch(updateRegistrationWorkflow);
    }

    string GetDemoUrl(SelectableRegistrationWorkflow workflow)
    {
        return Options.Value.IsReamEnabled ? $"{Options.Value.Issuer}/{activeRealm}/registration?workflowName={workflow.RegistrationWorkflow.Name}" : $"{Options.Value.Issuer}/registration?workflowName={workflow.RegistrationWorkflow.Name}";
    }

    async Task<string> GetRealm()
    {
        var realmStr = !string.IsNullOrWhiteSpace(realmStore.Realm) ? realmStore.Realm : SimpleIdServer.IdServer.Constants.DefaultRealm;
        return realmStr;
    }
}